package com.zhongen.oa.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zhongen.oa.service.InstanceProgressService;
import com.zhongen.wflow.bean.entity.WflowModelHistorys;
import com.zhongen.wflow.bean.entity.WflowSubProcess;
import com.zhongen.wflow.mapper.WflowModelHistorysMapper;
import com.zhongen.wflow.mapper.WflowSubProcessMapper;
import com.zhongen.wflow.workflow.bean.process.ProcessNode;
import com.zhongen.wflow.workflow.bean.process.form.Form;
import com.zhongen.wflow.workflow.config.WflowGlobalVarDef;
import com.zhongen.wflow.workflow.service.ProcessNodeCatchService;
import lombok.AllArgsConstructor;
import com.zhongen.wflow.workflow.service.FormService;
import org.flowable.engine.HistoryService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.variable.api.history.HistoricVariableInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
@AllArgsConstructor
public class InstanceProgressServiceImpl implements InstanceProgressService {

	@Autowired
	public HistoryService historyService;

	private final FormService formService;

	private final WflowSubProcessMapper subProcessMapper;

	private final ProcessNodeCatchService nodeCatchService;

	;

	private final WflowModelHistorysMapper modelHistorysMapper;

	@Override
	public JSONObject getInstanceProgressInfo(JSONObject param) {
		String instanceId = param.getString("instanceId");
		String nodeId = param.getString("nodeId");
		List<Form> forms = Collections.emptyList();
		List<Form> formItems = Collections.emptyList();
		Map<String, Object> formDatas = new HashMap<>();
		HistoricProcessInstance instance = historyService.createHistoricProcessInstanceQuery()
			.processInstanceId(instanceId)
			.singleResult();
		Long createId = Long.valueOf(instance.getStartUserId());
		// 数据分类 表单配置及数据、审批任务结果、
		forms = Collections.emptyList();
		// 是否是子流程
		boolean isSub = StrUtil.isNotBlank(instance.getSuperProcessInstanceId());
		HistoricProcessInstance mainInst = isSub ? null : instance;
		if (isSub) {
			// 查出主流程表单数据
			mainInst = historyService.createHistoricProcessInstanceQuery()
				.processInstanceId(instance.getSuperProcessInstanceId())
				.singleResult();
			formDatas = formService.getProcessInstanceFormData(mainInst.getId());
		}
		// 优化查询，把之前查好几次的一次性查出来然后再分类
		List<HistoricVariableInstance> variables = historyService.createHistoricVariableInstanceQuery()
			.processInstanceId(instanceId)
			.executionId(instanceId)
			.list();
		// 遍历所有变量，将数据分类
		for (HistoricVariableInstance var : variables) {
			if (!isSub && var.getVariableName().startsWith("field")) {
				formDatas.put(var.getVariableName(), var.getValue());
			}
			else if (!isSub && WflowGlobalVarDef.WFLOW_FORMS.equals(var.getVariableName())) {
				forms = (List<Form>) var.getValue();
			}
		}
		ProcessNode<?> currentNode = null;
		if (isSub) {
			WflowSubProcess subProcess = subProcessMapper.selectOne(new LambdaQueryWrapper<>(
					WflowSubProcess.builder().procDefId(instance.getProcessDefinitionId()).build()));
			currentNode = nodeCatchService.reloadProcessByStr(subProcess.getProcess()).get(nodeId);
			HistoricVariableInstance formsVar = historyService.createHistoricVariableInstanceQuery()
				.processInstanceId(mainInst.getId())
				.variableName(WflowGlobalVarDef.WFLOW_FORMS)
				.singleResult();
			forms = (List<Form>) formsVar.getValue();
			// 获取主流程节点配置信息
		}
		if (StrUtil.isNotBlank(nodeId)) {
			// 搜索当前版本流程的配置
			WflowModelHistorys modelHistory = modelHistorysMapper
				.selectOne(new LambdaQueryWrapper<>(WflowModelHistorys.builder()
					.processDefId(mainInst.getProcessDefinitionId())
					.version(mainInst.getProcessDefinitionVersion())
					.build()));
			currentNode = nodeCatchService.reloadProcessByStr(modelHistory.getProcess())
				.get(isSub ? instance.getBusinessKey() : nodeId);

		}
		// 表单的 currentNode 以主流程为准
		formItems = formService.filterFormAndDataByPermConfig(forms, formDatas, currentNode);
		JSONObject result = new JSONObject();
		result.put("createId", createId);
		result.put("formItems", formItems);
		result.put("formDatas", formDatas);
		return result;

	}

}
